﻿// MyLoggerAPI.h (公共接口头文件)
#ifndef MYLOGGER_API_H
#define MYLOGGER_API_H

// --- DLL 导出/导入宏 ---
// MYLOGGER_EXPORTS 宏应该只在构建 MyLogger DLL 时由项目定义
#ifdef MYLOGGER_EXPORTS
#define MYLOGGER_API __declspec(dllexport)
#else
#define MYLOGGER_API __declspec(dllimport)
#endif

// --- 必要的基础库包含 ---
#include <string>    // 宏需要 std::string
#include <iostream>  // 宏的错误处理需要 std::cerr
#include <exception> // 宏的错误处理需要 std::exception

// --- fmtlib 包含 ---
// 使用宏需要包含 fmtlib (通常由 spdlog 包含)
// 确保用户的项目可以找到这个头文件
#include <spdlog/fmt/fmt.h>

// --- Qt 类前向声明 (如果启用 Qt) ---
#ifdef QT_CORE_LIB
class QTextBrowser;
class QTextEdit;
#endif

// --- 公共 API 函数声明 ---
// 这些是用户直接调用的函数，用于配置日志记录器

/**
 * @brief 设置日志记录是否启用。
 * @param enabled true 表示启用日志，false 表示禁用。
 */
MYLOGGER_API void MyLogger_SetEnabled(bool enabled);

/**
 * @brief 检查日志记录当前是否启用。
 * @return 如果日志已启用，则返回 true；否则返回 false。
 */
MYLOGGER_API bool MyLogger_IsEnabled();

/**
 * @brief 设置日志文件轮转时保留的最大文件数量。
 * @param count 要保留的最大文件数。必须大于 0。
 * @note 这个设置应该在第一次记录日志之前调用才能生效。
 *       默认为 10。
 */
MYLOGGER_API void MyLogger_SetMaxFiles(int count);

#ifdef QT_CORE_LIB
/**
 * @brief 绑定一个 QTextBrowser 控件用于显示日志。
 * @param textBrowser 指向 QTextBrowser 控件的指针。传递 nullptr 可以取消绑定。
 */
MYLOGGER_API void MyLogger_BindBrowser(QTextBrowser* textBrowser);

/**
 * @brief 绑定一个 QTextEdit 控件用于显示日志。
 * @param textEdit 指向 QTextEdit 控件的指针。传递 nullptr 可以取消绑定。
 */
MYLOGGER_API void MyLogger_BindEdit(QTextEdit* textEdit);
#endif // QT_CORE_LIB


// --- 供宏调用的内部函数声明 ---
// 这些函数由下面的宏展开后调用，它们是 DLL 导出的实现细节。
// 用户不应直接调用这些 Internal_ 函数。
MYLOGGER_API void Internal_LogInfo(const char* file, int line, const char* function, const std::string& message);
MYLOGGER_API void Internal_LogWarn(const char* file, int line, const char* function, const std::string& message);
MYLOGGER_API void Internal_LogError(const char* file, int line, const char* function, const std::string& message);
MYLOGGER_API void Internal_LogCritical(const char* file, int line, const char* function, const std::string& message);
#ifdef QT_CORE_LIB
MYLOGGER_API void Internal_QtInfo(const char* file, int line, const char* function, const std::string& message);
MYLOGGER_API void Internal_QtWarn(const char* file, int line, const char* function, const std::string& message);
MYLOGGER_API void Internal_QtError(const char* file, int line, const char* function, const std::string& message);
MYLOGGER_API void Internal_QtCritical(const char* file, int line, const char* function, const std::string& message);
MYLOGGER_API void Internal_BothInfo(const char* file, int line, const char* function, const std::string& message);
MYLOGGER_API void Internal_BothWarn(const char* file, int line, const char* function, const std::string& message);
MYLOGGER_API void Internal_BothError(const char* file, int line, const char* function, const std::string& message);
MYLOGGER_API void Internal_BothCritical(const char* file, int line, const char* function, const std::string& message);
#endif // QT_CORE_LIB


// --- 函数名宏 ---
// 定义 __func__ (如果编译器不支持 C++11 标准)
#ifndef __func__
#ifdef _MSC_VER
#define __func__ __FUNCTION__
#else
#define __func__ __func__ // C++11 标准
#endif
#endif

// --- 日志宏定义 (简化名称) ---
// 这些宏是用户使用的主要接口。

// --- 文件/控制台日志宏 ---
#define LOG_INFO(fmt_str, ...) \
    do { \
        if (MyLogger_IsEnabled()) { /* 检查日志是否启用 */ \
            try { \
                /* 使用 fmt::format 格式化消息 */ \
                std::string formatted_msg = fmt::format(FMT_STRING(fmt_str), ##__VA_ARGS__); \
                /* 调用内部日志函数 */ \
                Internal_LogInfo(__FILE__, __LINE__, __func__, formatted_msg); \
            } catch (const std::exception& e) { \
                /* 格式化出错时输出到标准错误流 */ \
                std::cerr << "MyLogger FMT Error (LOG_INFO): " << e.what() << " in " << __FILE__ << ":" << __LINE__ << std::endl; \
            } catch (...) { \
                std::cerr << "MyLogger FMT Error (LOG_INFO): Unknown formatting error in " << __FILE__ << ":" << __LINE__ << std::endl; \
            } \
        } \
    } while(0) // 使用 do-while(0) 避免宏展开时的作用域问题

#define LOG_WARN(fmt_str, ...) \
    do { \
        if (MyLogger_IsEnabled()) { \
            try { \
                std::string formatted_msg = fmt::format(FMT_STRING(fmt_str), ##__VA_ARGS__); \
                Internal_LogWarn(__FILE__, __LINE__, __func__, formatted_msg); \
            } catch (const std::exception& e) { \
                std::cerr << "MyLogger FMT Error (LOG_WARN): " << e.what() << " in " << __FILE__ << ":" << __LINE__ << std::endl; \
            } catch (...) { \
                std::cerr << "MyLogger FMT Error (LOG_WARN): Unknown formatting error in " << __FILE__ << ":" << __LINE__ << std::endl; \
            } \
        } \
    } while(0)

#define LOG_ERROR(fmt_str, ...) \
    do { \
        if (MyLogger_IsEnabled()) { \
            try { \
                std::string formatted_msg = fmt::format(FMT_STRING(fmt_str), ##__VA_ARGS__); \
                Internal_LogError(__FILE__, __LINE__, __func__, formatted_msg); \
            } catch (const std::exception& e) { \
                std::cerr << "MyLogger FMT Error (LOG_ERROR): " << e.what() << " in " << __FILE__ << ":" << __LINE__ << std::endl; \
            } catch (...) { \
                std::cerr << "MyLogger FMT Error (LOG_ERROR): Unknown formatting error in " << __FILE__ << ":" << __LINE__ << std::endl; \
            } \
        } \
    } while(0)

#define LOG_CRITICAL(fmt_str, ...) \
    do { \
        if (MyLogger_IsEnabled()) { \
            try { \
                std::string formatted_msg = fmt::format(FMT_STRING(fmt_str), ##__VA_ARGS__); \
                Internal_LogCritical(__FILE__, __LINE__, __func__, formatted_msg); \
            } catch (const std::exception& e) { \
                std::cerr << "MyLogger FMT Error (LOG_CRITICAL): " << e.what() << " in " << __FILE__ << ":" << __LINE__ << std::endl; \
            } catch (...) { \
                std::cerr << "MyLogger FMT Error (LOG_CRITICAL): Unknown formatting error in " << __FILE__ << ":" << __LINE__ << std::endl; \
            } \
        } \
    } while(0)


// --- 仅 Qt 日志宏 ---
#ifdef QT_CORE_LIB
#define QT_INFO(fmt_str, ...) \
    do { \
        if (MyLogger_IsEnabled()) { \
            try { \
                std::string formatted_msg = fmt::format(FMT_STRING(fmt_str), ##__VA_ARGS__); \
                Internal_QtInfo(__FILE__, __LINE__, __func__, formatted_msg); \
            } catch (const std::exception& e) { \
                std::cerr << "MyLogger FMT Error (QT_INFO): " << e.what() << " in " << __FILE__ << ":" << __LINE__ << std::endl; \
            } catch (...) { \
                std::cerr << "MyLogger FMT Error (QT_INFO): Unknown formatting error in " << __FILE__ << ":" << __LINE__ << std::endl; \
            } \
        } \
    } while(0)

#define QT_WARN(fmt_str, ...) \
    do { \
        if (MyLogger_IsEnabled()) { \
            try { \
                std::string formatted_msg = fmt::format(FMT_STRING(fmt_str), ##__VA_ARGS__); \
                Internal_QtWarn(__FILE__, __LINE__, __func__, formatted_msg); \
            } catch (const std::exception& e) { \
                std::cerr << "MyLogger FMT Error (QT_WARN): " << e.what() << " in " << __FILE__ << ":" << __LINE__ << std::endl; \
            } catch (...) { \
                std::cerr << "MyLogger FMT Error (QT_WARN): Unknown formatting error in " << __FILE__ << ":" << __LINE__ << std::endl; \
            } \
        } \
    } while(0)

#define QT_ERROR(fmt_str, ...) \
    do { \
        if (MyLogger_IsEnabled()) { \
            try { \
                std::string formatted_msg = fmt::format(FMT_STRING(fmt_str), ##__VA_ARGS__); \
                Internal_QtError(__FILE__, __LINE__, __func__, formatted_msg); \
            } catch (const std::exception& e) { \
                std::cerr << "MyLogger FMT Error (QT_ERROR): " << e.what() << " in " << __FILE__ << ":" << __LINE__ << std::endl; \
            } catch (...) { \
                std::cerr << "MyLogger FMT Error (QT_ERROR): Unknown formatting error in " << __FILE__ << ":" << __LINE__ << std::endl; \
            } \
        } \
    } while(0)

#define QT_CRITICAL(fmt_str, ...) \
    do { \
        if (MyLogger_IsEnabled()) { \
            try { \
                std::string formatted_msg = fmt::format(FMT_STRING(fmt_str), ##__VA_ARGS__); \
                Internal_QtCritical(__FILE__, __LINE__, __func__, formatted_msg); \
            } catch (const std::exception& e) { \
                std::cerr << "MyLogger FMT Error (QT_CRITICAL): " << e.what() << " in " << __FILE__ << ":" << __LINE__ << std::endl; \
            } catch (...) { \
                std::cerr << "MyLogger FMT Error (QT_CRITICAL): Unknown formatting error in " << __FILE__ << ":" << __LINE__ << std::endl; \
            } \
        } \
    } while(0)

// --- 同时输出到文件/控制台和 Qt 的宏 ---
#define LOG_BOTH_INFO(fmt_str, ...) \
    do { \
        if (MyLogger_IsEnabled()) { \
            try { \
                std::string formatted_msg = fmt::format(FMT_STRING(fmt_str), ##__VA_ARGS__); \
                Internal_BothInfo(__FILE__, __LINE__, __func__, formatted_msg); \
            } catch (const std::exception& e) { \
                std::cerr << "MyLogger FMT Error (LOG_BOTH_INFO): " << e.what() << " in " << __FILE__ << ":" << __LINE__ << std::endl; \
            } catch (...) { \
                std::cerr << "MyLogger FMT Error (LOG_BOTH_INFO): Unknown formatting error in " << __FILE__ << ":" << __LINE__ << std::endl; \
            } \
        } \
    } while(0)

#define LOG_BOTH_WARN(fmt_str, ...) \
    do { \
        if (MyLogger_IsEnabled()) { \
            try { \
                std::string formatted_msg = fmt::format(FMT_STRING(fmt_str), ##__VA_ARGS__); \
                Internal_BothWarn(__FILE__, __LINE__, __func__, formatted_msg); \
            } catch (const std::exception& e) { \
                std::cerr << "MyLogger FMT Error (LOG_BOTH_WARN): " << e.what() << " in " << __FILE__ << ":" << __LINE__ << std::endl; \
            } catch (...) { \
                std::cerr << "MyLogger FMT Error (LOG_BOTH_WARN): Unknown formatting error in " << __FILE__ << ":" << __LINE__ << std::endl; \
            } \
        } \
    } while(0)

#define LOG_BOTH_ERROR(fmt_str, ...) \
    do { \
        if (MyLogger_IsEnabled()) { \
            try { \
                std::string formatted_msg = fmt::format(FMT_STRING(fmt_str), ##__VA_ARGS__); \
                Internal_BothError(__FILE__, __LINE__, __func__, formatted_msg); \
            } catch (const std::exception& e) { \
                std::cerr << "MyLogger FMT Error (LOG_BOTH_ERROR): " << e.what() << " in " << __FILE__ << ":" << __LINE__ << std::endl; \
            } catch (...) { \
                std::cerr << "MyLogger FMT Error (LOG_BOTH_ERROR): Unknown formatting error in " << __FILE__ << ":" << __LINE__ << std::endl; \
            } \
        } \
    } while(0)

#define LOG_BOTH_CRITICAL(fmt_str, ...) \
    do { \
        if (MyLogger_IsEnabled()) { \
            try { \
                std::string formatted_msg = fmt::format(FMT_STRING(fmt_str), ##__VA_ARGS__); \
                Internal_BothCritical(__FILE__, __LINE__, __func__, formatted_msg); \
            } catch (const std::exception& e) { \
                std::cerr << "MyLogger FMT Error (LOG_BOTH_CRITICAL): " << e.what() << " in " << __FILE__ << ":" << __LINE__ << std::endl; \
            } catch (...) { \
                std::cerr << "MyLogger FMT Error (LOG_BOTH_CRITICAL): Unknown formatting error in " << __FILE__ << ":" << __LINE__ << std::endl; \
            } \
        } \
    } while(0)

#endif // QT_CORE_LIB


#endif // MYLOGGER_API_H